<style scoped lang="less">
.scroll-bar{
  position: absolute;
  background: v-bind(color);
  border-radius: 10px;
  transition: opacity ease-in-out 300ms;
  opacity: 0;
  &-show{ opacity: 1 }
}
</style>
<template>
  <div class="scroll-bar" ref="yBar"  :class="{'scroll-bar-show':show}" />
</template>

<script lang="ts" setup>
import {clearTimer, setTimer} from "@/helper";
import {computed, onMounted, ref} from "vue";
import { dragEvent } from "@/helper";

const props = defineProps({
  parentNode: { type:Element, default: null },
  barOptions: { type: Object, default :() => ({}) }
})


const width = computed(() => props.barOptions?.width ?? 5)
const color = computed(() => props.barOptions?.color ?? 'rgb(224,224,224)')
const gap = computed(() => props.barOptions?.gap ?? 10)
const position = computed(() => ['left','right'].includes(props.barOptions?.position) ? props.barOptions?.position :  'right')


let timer:number // 显示定时器
let show = ref(true) // 显示状态
const yBar = ref(null)
let ratio = 1 // 滚动条换算比例
const showBar = () => {
  if(timer) clearTimer(timer)
  show.value = true
  timer = setTimer(() => { show.value = false },300,1)
}
/** renderBar */
const renderBar = () => {
  showBar()
  props.parentNode.addEventListener('mousemove', () => showBar())
  const { scrollHeight,scrollTop,offsetWidth,offsetHeight,scrollLeft } = props?.parentNode
  const barHeight = offsetHeight >= scrollHeight ? 0 : offsetHeight / 1.2
  ratio = (scrollHeight - offsetHeight) / (offsetHeight - barHeight)
  yBar.value.style.top = `${scrollTop + (scrollTop/ratio)}px`
  yBar.value.style.height =  `${barHeight}px`
  yBar.value.style.width =  `${width.value}px`
  yBar.value.style.left = scrollLeft + (position.value === 'left' ? gap.value : offsetWidth - width.value - gap.value) + 'px'
}
defineExpose({ renderBar })

let parentScrollTop = 0 // 父节点滚动距离
onMounted(() => {
  dragEvent(
      yBar.value,
      null,
      false,
      event => {
    const { dragY } = event
    props.parentNode.scrollTo({top:parentScrollTop + dragY * ratio})
  }, () => {
    parentScrollTop =  props?.parentNode?.scrollTop
  })
})
</script>

